/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */

/* 
 * Hum -- The Low Calorie Music Manager
 * 
 * Copyright (C) 2007 by Brian Davis <brian.william.davis@gmail.com>
 *
 * This file is modifiable/redistributable under the terms of the GNU
 * General Public License.
 *
 * You should have recieved a copy of the GNU General Public License along
 * with this program; see the file COPYING. If not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 0211-1307, USA.
 */

#include "hum_utils.h"
#include "hum_ui.h"
#include "hum_player.h"

// FIXME: These should not be here. At all. 
gboolean hum_get_player_position (GstElement *pipeline);
void hum_bus_message_error ();
void hum_bus_message_eos ();

void
hum_bus_message_error ()
{
	hum_debug (__func__, "Error in stream.\n");
	g_signal_emit_by_name ((gpointer) hum_app.next_button, "clicked", NULL);
}

// FIXME: This behavior should depend on a user-defined "loop playback" setting.
void
hum_bus_message_eos ()
{
	/* FIXME: Implement a convenience function along the lines of 
	          "gboolean hum_get_next_track" that will return TRUE if one exists
	          (and might optionally loop back to the beginning if not) and 
	          queues the next song for playing. 
	*/
	hum_debug (__func__, "End of file reached.\n");
	g_signal_emit_by_name ((gpointer) hum_app.next_button, "clicked", NULL);
}

gboolean
hum_get_player_position (GstElement *pipeline)
{
	GstFormat fmt = GST_FORMAT_TIME;
	gint64 pos, len;
	
	if (gst_element_query_position (pipeline, &fmt, &pos)
		&& gst_element_query_duration (pipeline, &fmt, &len)) 
	{
		// The slider's range is between 0.0 and 1,000,000.0 to be accurate to 
		// the nanosecond. 
		gdouble progress = ((gdouble) pos / (gdouble) len) * 1000000.0;
		pos = pos / GST_SECOND;
		len = len / GST_SECOND;
		
		gtk_range_set_value (GTK_RANGE (hum_app.slider), progress);
		
		// FIXME: This goes crazy on VBR songs...
		if (HUM_SECONDS_TO_HOURS(len) > 0)
		{
			guint pos_hour = (guint) (pos / (60 * 60));
			guint pos_minute = (guint) (pos / 60);
			guint pos_second = (guint) (pos % 60);
			guint len_hour = (guint) (len / (60 * 60));
			guint len_minute = (guint) (len / 60);
			guint len_second = (guint) (len % 60);
			
			gtk_label_set_text (hum_app.duration_label, g_strdup_printf ("%u:%02u:%02u of %u:%02u:%02u", pos_hour, pos_minute, pos_second, len_hour, len_minute, len_second));
		}
		else
		{
			guint pos_minute = (guint) (pos / 60);
			guint pos_second = (guint) (pos % 60);
			guint len_minute = (guint) (len / 60);
			guint len_second = (guint) (len % 60);
			
			gtk_label_set_text (hum_app.duration_label, g_strdup_printf ("%u:%02u of %u:%02u", pos_minute, pos_second, len_minute, len_second));
		}
	}
	
	/* call me again */
	return TRUE;
}

void
hum_init ()
{
	/* Connect to Tracker. */
	hum_debug (__func__, "Connecting to Tracker...\n");
	hum_app.client = tracker_connect (FALSE);
	
	if (!hum_app.client)
	{
		hum_debug (__func__, "Could not initialize Tracker - exiting...\n");
		hum_quit ();
	}
	
	/* Initialize important stats. */
	hum_app.total_song_count = 0;
	hum_app.total_duration = 0;
	hum_app.total_song_size = 0;
	
	/* Initialize the UI. */
	hum_init_ui();
	
	/* Initialize the Gstreamer framework. */
	hum_init_player();
	g_timeout_add (200, (GSourceFunc) hum_get_player_position, GST_PIPELINE (hum_player.pipeline));
	g_signal_connect (hum_player.bus, "message::error", G_CALLBACK (hum_bus_message_error), NULL);
	g_signal_connect (hum_player.bus, "message::eos", G_CALLBACK (hum_bus_message_eos), NULL);
}

void
hum_quit ()
{
	tracker_disconnect (hum_app.client);
	
	gst_element_set_state (hum_player.pipeline, GST_STATE_NULL);
	gst_object_unref (GST_OBJECT (hum_player.pipeline));
	gst_object_unref (hum_player.bus);
	
	//g_free (audio_keys);
	//g_free (hum_app.client);
	//g_free (hum_app.store);
	
	//g_free (hum_app.slider);
	//g_free (hum_app.duration_label);
	//g_free (hum_app.track_label);
	//g_free (hum_app.next_button);
	//g_free (hum_app.stop_button);
	//g_free (hum_app.play_button);
	//g_free (hum_app.prev_button);
	//g_free (hum_app.window);
	//g_free (hum_app.xml);
	
	//if (hum_player.uri)
	//	g_free (hum_player.uri);
	
	gtk_main_quit ();
}

int
main (int argc, char *argv[])
{
#ifdef ENABLE_NLS
	bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);
#endif
	
	/* Initialize threads. */
	//if (!g_thread_supported ())
	//	g_thread_init (NULL);
	//gdk_threads_init ();

	gtk_set_locale ();
	gtk_init (&argc, &argv);

	hum_init ();
	gtk_widget_show (GTK_WIDGET (hum_app.window));

	//gdk_threads_enter();
	gtk_main ();
	//gdk_threads_leave();
	return 0;
}
